package com.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dto.ItemMinuteSaveDto;
import com.dto.ItemSaveDto;
import com.dto.PageDTO;
import com.exceptions.UpLoadFailedException;
import com.mapper.*;
import com.po.*;
import com.query.ItemQuery;
import com.service.ItemMinuteService;
import com.service.ItemService;
import com.utils.AliOssUtil;
import com.vo.ItemCommentVo;
import com.vo.ItemPageVo;
import com.vo.ItemVo;
import com.vo.UserVo;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.time.LocalDateTime;
import java.util.*;

@Service
@Slf4j
@RequiredArgsConstructor
public class ItemServiceImpl extends ServiceImpl<ItemMapper, Item> implements ItemService {

    private final AliOssUtil aliOssUtil;

    private final ItemMinuteMapper itemMinuteMapper;

    private final ItemMapper itemMapper;

    private final ItemMinuteService itemMinuteService;

    private final CommentMapper commentMapper;

    private final OrderDetailMapper orderDetailMapper;

    private final OrderMapper orderMapper;

    private final UserMapper userMapper;

    @Override
    @Transactional
    public void isave(ItemSaveDto itemSaveDto, MultipartFile image) {
        Item item = new Item();
        BeanUtil.copyProperties(itemSaveDto,item);
        String filePath;
        try {
            //原始文件名
            String originalFilename = image.getOriginalFilename();
            String extention = originalFilename.substring(originalFilename.lastIndexOf("."));
            String objectname = UUID.randomUUID().toString() + extention;
            filePath = aliOssUtil.upload(image.getBytes(), objectname);
        }catch (Exception e){
            throw new UpLoadFailedException("文件上传失败！");
        }
        item.setImage(filePath);
        item.setIcreate(StpUtil.getLoginIdAsLong());
        item.setCreateTime(LocalDateTime.now());
        item.setUserId(StpUtil.getLoginIdAsLong());
        if (item.getMinuteStatus() == 1){
            itemSaveDto.getItem_minuteList().forEach(item_minute -> {
                ItemMinute item_minute1 = new ItemMinute();
                BeanUtil.copyProperties(item_minute,item_minute1);
                item_minute1.setItemId(item.getId());
                itemMinuteMapper.insert(item_minute1);
            });
        }
        save(item);

    }

    @Override
    @Transactional
    public void iupdate(Long id,String status) {
        //修改商品status
        UpdateWrapper<Item> wrapper = new UpdateWrapper<Item>()
                .setSql("status = " + status)
                .in("id", id);
        update(null,wrapper);
        LambdaQueryWrapper<ItemMinute> eq = new LambdaQueryWrapper<ItemMinute>()
                .eq(ItemMinute::getItemId, id);
        //取出商品包含的单品信息
        List<ItemMinute> itemMinutes = itemMinuteMapper.selectList(eq);
        //修改单品的status
        if (CollUtil.isNotEmpty(itemMinutes)) {
            itemMinutes.forEach(itemMinute -> {
                UpdateWrapper<ItemMinute> wrapper1 = new UpdateWrapper<ItemMinute>()
                        .setSql("status = " + status)
                        .in("id", itemMinute.getId());
                itemMinuteMapper.update(null,wrapper1);
            });
        }
    }

    @Override
    public ItemVo get(Long id) {
        LambdaQueryWrapper<Item> eq = new LambdaQueryWrapper<Item>()
                .eq(Item::getId, id)
                .eq(Item::getStatus, 1);
        Item item = itemMapper.selectOne(eq);
        String[] split = item.getImage().split(",");
        log.info("item:{}",item);
        ItemVo itemVo = new ItemVo();
        BeanUtil.copyProperties(item,itemVo);
        List<String> image=new ArrayList<>();
        for (int i=0;i< split.length-1;i++){
            image.add(split[i]);
        }
        //查询itemminute
        LambdaQueryWrapper<ItemMinute> getminute = new LambdaQueryWrapper<ItemMinute>()
                .eq(ItemMinute::getItemId, item.getId());
        List<ItemMinute> itemMinutes = itemMinuteMapper.selectList(getminute);
        itemVo.setItemMinuteList(itemMinutes);
        //查询商品对应的评论
        LambdaQueryWrapper<Comment> wrapper = new LambdaQueryWrapper<Comment>()
                .eq(Comment::getItemId, id);
        List<Comment> comments = commentMapper.selectList(wrapper);
        List<ItemCommentVo> itemCommentVoList = new ArrayList<>();
        comments.forEach(comment -> {
            ItemCommentVo itemCommentVo = new ItemCommentVo();
            BeanUtil.copyProperties(comment,itemCommentVo);
            String commentImage = comment.getImage();
            String[] split1 = commentImage.split(",");
            List<String> images=new ArrayList<>();
            for (int i=0;i< split1.length-1;i++){
                images.add(split1[i]);
            }
            itemCommentVo.setImage(images);
            itemCommentVoList.add(itemCommentVo);
        });
        itemVo.setItemCommentVoList(itemCommentVoList);
        return itemVo;
    }

    @Override
    public PageDTO<ItemPageVo> ipage(ItemQuery itemQuery) {
        //构建分页条件
        Page<Item> page = Page.of(itemQuery.getPageNo(),itemQuery.getPageSize());
        //构建排序条件
        if (StrUtil.isNotBlank(itemQuery.getSortBy())){
            page.addOrder(new OrderItem(itemQuery.getSortBy(),itemQuery.getIsAsc()));
        }else {
            page.addOrder(new OrderItem("sold",false));
        }
        //构建查询条件
        Page<Item> itemPage = lambdaQuery()
                .like(itemQuery.getName() != null&&itemQuery.getName()!="", Item::getName, itemQuery.getName())
                .eq(itemQuery.getCategory() != null&&itemQuery.getCategory()!="", Item::getCategory, itemQuery.getCategory())
                .eq(itemQuery.getBrand() != null&&itemQuery.getBrand()!="", Item::getBrand,itemQuery.getBrand())
                .eq(itemQuery.getUserId()!= null, Item::getUserId,itemQuery.getUserId())
                .ge(itemQuery.getMinPrice() != null,Item::getPrice, itemQuery.getMinPrice())
                .le(itemQuery.getMaxPrice() != null, Item::getPrice, itemQuery.getMaxPrice())
                .page(page);
        PageDTO<ItemPageVo> itemVoPageDTO = new PageDTO<>();
        itemVoPageDTO.setTotal(itemPage.getTotal());
        itemVoPageDTO.setPages(itemPage.getPages());
        List<Item> records = itemPage.getRecords();
        if (CollUtil.isNotEmpty(records)) {
            List<ItemPageVo> itemPageVoList = new ArrayList<>();
            records.forEach(record -> {
                ItemPageVo itemPageVo = new ItemPageVo();
                String[] split = record.getImage().split(",");
                List<String> image=new ArrayList<>();
                for (int i=0;i< split.length;i++){
                    image.add(split[i]);
                }
                BeanUtil.copyProperties(record,itemPageVo);
                itemPageVo.setImage(image);
                itemPageVoList.add(itemPageVo);
            });
            itemVoPageDTO.setList(itemPageVoList);
        }

        return itemVoPageDTO;
    }

    /**
     *处理前端所传信息
     * @param name
     * @param image
     * @param price
     * @param stock
     * @param category
     * @param brand
     * @param minuteStatus
     * @param ItemMinuteName
     * @param ItemMinutePrice
     * @param ItemMinuteStatus
     * @param ItemMinuteImage
     * @param spec
     * @return
     */
    public ItemSaveDto getitemsavedto( String name , List<MultipartFile> image, Integer price, Integer stock, String category, String brand, Integer minuteStatus,List<String> ItemMinuteName,
                                       List<Integer>ItemMinutePrice,List<Integer>ItemMinuteStatus, List<MultipartFile>ItemMinuteImage,String spec){
        ItemSaveDto itemSaveDto=new ItemSaveDto();
        itemSaveDto.setName(name);
        itemSaveDto.setImage(image);
        itemSaveDto.setPrice(price);
        itemSaveDto.setStock(stock);
        itemSaveDto.setCategory(category);
        itemSaveDto.setBrand(brand);
        itemSaveDto.setMinuteStatus(minuteStatus);
        if (CollUtil.isNotEmpty(ItemMinuteName)) {
            List<ItemMinuteSaveDto> itemMinuteSaveDtos=new ArrayList<>();
            int size = ItemMinuteName.size();
            for (int i=0;i<size;i++){
                ItemMinuteSaveDto itemMinuteSaveDto=new ItemMinuteSaveDto();
                itemMinuteSaveDto.setName(ItemMinuteName.get(i));
                itemMinuteSaveDto.setPrice(ItemMinutePrice.get(i));
                itemMinuteSaveDto.setStatus(ItemMinuteStatus.get(i));
                itemMinuteSaveDto.setFile(ItemMinuteImage.get(i));
                itemMinuteSaveDtos.add(itemMinuteSaveDto);
            }

            itemSaveDto.setItem_minuteList(itemMinuteSaveDtos);
        }
        itemSaveDto.setSpec(spec);
        return itemSaveDto;
    }

    /**
     * 新增商品
     * @param itemSaveDto
     */
    @Transactional
    @Override
    public void saveItems(ItemSaveDto itemSaveDto) {
        //存入item表
        Item item=new Item();
        List<MultipartFile> file = itemSaveDto.getImage();
        String filePath="";
        String finalFilePath="";
        for (MultipartFile file1:file){
            try {
                //原始文件名
                String originalFilename = file1.getOriginalFilename();
                String extention = originalFilename.substring(originalFilename.lastIndexOf("."));
                String objectname = UUID.randomUUID().toString() + extention;
                filePath = aliOssUtil.upload(file1.getBytes(), objectname);
                finalFilePath+=filePath+",";
            }catch (Exception e){
                throw new UpLoadFailedException("文件上传失败！");
            }
        }
        BeanUtil.copyProperties(itemSaveDto,item);
        log.info("finalFilepath:{}",finalFilePath);
        item.setImage(finalFilePath);
        item.setIcreate(StpUtil.getLoginIdAsLong());
        item.setCreateTime(LocalDateTime.now());
        item.setUserId(StpUtil.getLoginIdAsLong());
        item.setUpdateTime(LocalDateTime.now());
        item.setIupdate(StpUtil.getLoginIdAsLong());
        //status和sold
        item.setStatus(1);
        item.setSold(0);
        //存入item
        this.save(item);
        log.info("item主键:{}",item.getId());
        //存入单品
        List<ItemMinuteSaveDto> itemMinuteList = itemSaveDto.getItem_minuteList();
        if (CollUtil.isNotEmpty(itemMinuteList)){
            for (ItemMinuteSaveDto itemMinuteSaveDto:itemMinuteList){
                ItemMinute itemMinute=new ItemMinute();
                BeanUtil.copyProperties(itemMinuteSaveDto,itemMinute);
                itemMinute.setItemId(item.getId());
                try {
                    //原始文件名
                    String originalFilename =itemMinuteSaveDto.getFile().getOriginalFilename();
                    String extention = originalFilename.substring(originalFilename.lastIndexOf("."));
                    String objectname = UUID.randomUUID().toString() + extention;
                    filePath = aliOssUtil.upload(itemMinuteSaveDto.getFile().getBytes(), objectname);
                }catch (Exception e){
                    throw new UpLoadFailedException("文件上传失败！");
                }
                itemMinute.setImage(filePath);
                itemMinuteService.save(itemMinute);
                log.info("itemMinute:{}",itemMinute);
        }
        }
        log.info("item:{}",item);
    }

    @Override
    public void put(Long id, ItemSaveDto itemSaveDto) {
        //判断是否更新照片
        String finalFilePath="";
        if (CollUtil.isNotEmpty(itemSaveDto.getImage())){
            List<MultipartFile> file = itemSaveDto.getImage();
            String filePath="";
            for (MultipartFile file1:file){
                try {
                    //原始文件名
                    String originalFilename = file1.getOriginalFilename();
                    String extention = originalFilename.substring(originalFilename.lastIndexOf("."));
                    String objectname = UUID.randomUUID().toString() + extention;
                    filePath = aliOssUtil.upload(file1.getBytes(), objectname);
                    finalFilePath+=filePath+",";
                }catch (Exception e){
                    throw new UpLoadFailedException("文件上传失败！");
                }
            }
        }
        //构建更新条件
        LambdaUpdateWrapper<Item> in = new LambdaUpdateWrapper<Item>()
                .set(itemSaveDto.getName() != null && !itemSaveDto.getName().equals(""), Item::getName, itemSaveDto.getName())
                .set(itemSaveDto.getPrice() != null, Item::getPrice, itemSaveDto.getPrice())
                .set(itemSaveDto.getStock() != null, Item::getStock, itemSaveDto.getStock())
                .set(itemSaveDto.getCategory() != null && !itemSaveDto.getCategory().equals(""), Item::getCategory, itemSaveDto.getCategory())
                .set(itemSaveDto.getBrand() != null && !itemSaveDto.getBrand().equals(""), Item::getBrand, itemSaveDto.getBrand())
                .set(itemSaveDto.getMinuteStatus() != null, Item::getMinuteStatus, itemSaveDto.getMinuteStatus())
                .set(itemSaveDto.getSpec() != null && !itemSaveDto.getSpec().equals(""), Item::getSpec, itemSaveDto.getSpec())
                .set(!finalFilePath.equals(""), Item::getImage, finalFilePath)
                .in(Item::getId, id);
        update(null,in);
        //判断是否更新单品数据
        if (CollUtil.isNotEmpty(itemSaveDto.getItem_minuteList())){
            LambdaQueryWrapper<ItemMinute> eq = new LambdaQueryWrapper<ItemMinute>()
                    .eq(ItemMinute::getItemId, id);
            //删除原本单品数据
            itemMinuteMapper.delete(eq);
            List<ItemMinuteSaveDto> itemMinuteList = itemSaveDto.getItem_minuteList();
            //将新的单品数据插入
            for (ItemMinuteSaveDto itemMinuteSaveDto:itemMinuteList){
                ItemMinute itemMinute=new ItemMinute();
                BeanUtil.copyProperties(itemMinuteSaveDto,itemMinute);
                itemMinute.setItemId(id);
                String filePath = "";
                try {
                    //原始文件名
                    String originalFilename =itemMinuteSaveDto.getFile().getOriginalFilename();
                    String extention = originalFilename.substring(originalFilename.lastIndexOf("."));
                    String objectname = UUID.randomUUID().toString() + extention;
                    filePath = aliOssUtil.upload(itemMinuteSaveDto.getFile().getBytes(), objectname);
                }catch (Exception e){
                    throw new UpLoadFailedException("文件上传失败！");
                }
                itemMinute.setImage(filePath);
                itemMinuteService.save(itemMinute);
            }
        }
    }

    @Override
    public List<UserVo> userList(Long id) {
        LambdaQueryWrapper<OrderDetail> eq = new LambdaQueryWrapper<OrderDetail>()
                .eq(OrderDetail::getItemId, id);
        List<OrderDetail> orderDetails = orderDetailMapper.selectList(eq);
        Set<Long> ids = new HashSet<>();
        orderDetails.forEach(orderDetail -> {
            Orders orders = orderMapper.selectById(orderDetail.getOrderId());
            ids.add(orders.getUserId());
        });
        List<UserVo> userVoList = new ArrayList<>();
        ids.forEach(i -> {
            UserVo userVo = new UserVo();
            User user = userMapper.selectById(i);
            BeanUtil.copyProperties(user,userVo);
            userVoList.add(userVo);
        });
        return userVoList;
    }
}
